from rest_framework import viewsets, permissions, status, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from django.utils import timezone
from django_filters.rest_framework import DjangoFilterBackend
from .models import DeliveryArea, DeliverymanArea, DeliveryTask, DeliveryStatusRecord
from .serializers import DeliveryAreaSerializer, DeliverymanAreaSerializer, DeliveryTaskSerializer, DeliveryStatusRecordSerializer
from users.permissions import DeliverymanPermission, IsAdmin, DeliveryAdminPermission
from django.db.models import Count
from users.decorators import require_delivery_permission  # 添加这一行导入装饰器

class DeliveryAreaViewSet(viewsets.ModelViewSet):
    queryset = DeliveryArea.objects.all()
    serializer_class = DeliveryAreaSerializer
    # 移除权限检查
    # permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter]
    search_fields = ['name']
    
    # 移除权限方法
    # def get_permissions(self):
    #     if self.action in ['create', 'update', 'partial_update', 'destroy']:
    #         return [IsAdmin()|DeliveryAdminPermission()]
    #     return [permissions.IsAuthenticated()]

class DeliverymanAreaViewSet(viewsets.ModelViewSet):
    queryset = DeliverymanArea.objects.all()
    serializer_class = DeliverymanAreaSerializer
    # 移除权限检查
    # permission_classes = [permissions.IsAuthenticated]
    
    # 移除权限方法
    # def get_permissions(self):
    #     if self.action in ['create', 'update', 'partial_update', 'destroy']:
    #         return [IsAdmin()|DeliveryAdminPermission()]
    #     return [permissions.IsAuthenticated()]
    
    def get_queryset(self):
        # 修改为返回所有数据，不再根据用户角色过滤
        return DeliverymanArea.objects.all()

class DeliveryTaskViewSet(viewsets.ModelViewSet):
    queryset = DeliveryTask.objects.all()
    serializer_class = DeliveryTaskSerializer
    # 移除权限检查
    # permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['status', 'deliveryman', 'priority']
    search_fields = ['delivery_number', 'sales_order__order_number', 'sales_order__customer__username']
    ordering_fields = ['created_at', 'priority', 'estimated_delivery_time']
    ordering = ['-created_at']
    
    # 移除权限方法
    # def get_permissions(self):
    #     if self.action in ['create', 'update', 'partial_update', 'destroy']:
    #         return [IsAdmin() | DeliveryAdminPermission()]
    #     elif self.action in ['assign', 'update_status']:
    #         return [DeliverymanPermission() | IsAdmin() | DeliveryAdminPermission()]
    #     return [permissions.IsAuthenticated()]
    
    def get_queryset(self):
        # 修改为返回所有数据，不再根据用户角色过滤
        return DeliveryTask.objects.all()
    
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        
        # 处理查询参数
        order_number = request.query_params.get('order_number')
        customer_name = request.query_params.get('customer_name')
        
        if order_number:
            queryset = queryset.filter(sales_order__order_number__icontains=order_number)
        if customer_name:
            queryset = queryset.filter(sales_order__customer__username__icontains=customer_name)
        
        # 自定义排序：将等待手动分配且被拒绝两次及以上的任务排在最前面
        # 使用Case/When进行条件排序
        from django.db.models import Case, When, Value, IntegerField
        
        queryset = queryset.annotate(
            custom_order=Case(
                # 第一优先级：等待手动分配且拒绝次数>=2的任务
                When(status='awaiting_manual_assignment', rejection_count__gte=2, then=Value(1)),
                # 第二优先级：其他任务
                default=Value(2),
                output_field=IntegerField()
            )
        ).order_by('custom_order', '-created_at')  # 首先按自定义顺序，然后按创建时间降序
        
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response({
                'code': 200,
                'message': '获取成功',
                'data': {
                    'total': self.paginator.page.paginator.count,
                    'items': serializer.data
                }
            })
        
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': {
                'items': serializer.data
            }
        })
    
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'])
    def assign(self, request, pk=None):
        """分配配送任务"""
        delivery_task = self.get_object()
        deliveryman_id = request.data.get('deliveryman_id')
        priority = request.data.get('priority')
        estimated_delivery_time = request.data.get('estimated_delivery_time')
        note = request.data.get('note')
        
        # 更新配送任务
        if deliveryman_id:
            delivery_task.deliveryman_id = deliveryman_id
            delivery_task.status = 'assigned'
            delivery_task.note = note if not delivery_task.note else f"{delivery_task.note}\n{note}"
            delivery_task.save()
            
            # 移除这段代码，不再在强制分配时更新订单状态
            # if delivery_task.sales_order and delivery_task.sales_order.status == 'paid':
            #     delivery_task.sales_order.status = 'shipped'
            #     delivery_task.sales_order.save()
        
        if priority:
            delivery_task.priority = priority
            
        if estimated_delivery_time:
            delivery_task.estimated_delivery_time = estimated_delivery_time
            
        if note:
            delivery_task.note = note
            
        delivery_task.save()
        
        # 创建状态记录
        DeliveryStatusRecord.objects.create(
            delivery_task=delivery_task,
            status='assigned',
            operator=request.user,
            note=f"任务已分配给配送员ID: {deliveryman_id}"
        )
        
        return Response({
            'code': 200,
            'message': '分配成功'
        })
    
    @action(detail=True, methods=['post'])
    def status(self, request, pk=None):
        """更新配送任务状态"""
        delivery_task = self.get_object()
        new_status = request.data.get('status')
        location = request.data.get('location', '')
        note = request.data.get('note', '')
        
        if new_status not in dict(DeliveryTask.STATUS_CHOICES):
            return Response({
                'code': 400,
                'message': '无效的状态'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 更新配送任务状态
        delivery_task.status = new_status
        
        # 如果状态是已完成，记录实际配送时间并更新订单状态
        if new_status == 'completed':
            delivery_task.actual_delivery_time = timezone.now()
            # 更新订单状态
            delivery_task.sales_order.status = 'completed'
            delivery_task.sales_order.save()
        # 如果状态是配送中，确保订单状态为已发货，并减少库存
        elif new_status == 'delivering':
            if delivery_task.sales_order and delivery_task.sales_order.status != 'shipped':
                # 更新订单状态为已发货
                delivery_task.sales_order.status = 'shipped'
                delivery_task.sales_order.save()
                
                # 减少库存
                from warehouse.models import Inventory, InventoryRecord
                order = delivery_task.sales_order
                
                # 遍历订单项，减少对应仓库的库存
                for order_item in order.items.all():
                    try:
                        inventory = Inventory.objects.get(
                            product_id=order_item.product_id, 
                            warehouse_id=order_item.warehouse_id
                        )
                        
                        # 检查库存是否足够
                        if inventory.current_stock < order_item.quantity:
                            # 库存不足，记录错误但继续处理
                            note += f"\n商品 {order_item.product.name} 库存不足，当前库存: {inventory.current_stock}, 需要: {order_item.quantity}"
                            continue
                        
                        # 减少库存
                        inventory.current_stock -= order_item.quantity
                        inventory.save()
                        
                        # 创建库存记录
                        InventoryRecord.objects.create(
                            inventory=inventory,
                            quantity=order_item.quantity,
                            operation_type='out',
                            operator=request.user,
                            related_order=order,
                            note=f'销售订单 {order.order_number} 出库 (配送任务状态变更为配送中)'
                        )
                    except Inventory.DoesNotExist:
                        # 库存记录不存在，记录错误但继续处理
                        note += f"\n商品ID {order_item.product_id} 在仓库ID {order_item.warehouse_id} 不存在库存记录"
        
        delivery_task.save()
        
        # 创建状态记录
        DeliveryStatusRecord.objects.create(
            delivery_task=delivery_task,
            status=new_status,
            operator=request.user,
            location=location,
            note=note
        )
        
        return Response({
            'code': 200,
            'message': '更新成功'
        })

class DeliveryStatusRecordViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = DeliveryStatusRecord.objects.all()
    serializer_class = DeliveryStatusRecordSerializer
    # 移除权限检查
    # permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['delivery_task', 'status']
    
    def get_queryset(self):
        # 修改为返回所有数据，不再根据用户角色过滤
        return DeliveryStatusRecord.objects.all()

@action(detail=False, methods=['get'])
# @require_delivery_permission  # 已移除权限装饰器
def delivery_staff(request):
    """获取配送员列表"""
    from users.models import User
    from users.serializers import UserSerializer
    
    # 获取所有配送员
    deliverymen = User.objects.filter(role='deliveryman')
    
    # 统计每个配送员的任务数量
    deliverymen = deliverymen.annotate(task_count=Count('delivery_tasks'))
    
    # 序列化数据
    data = []
    for deliveryman in deliverymen:
        user_data = UserSerializer(deliveryman).data
        areas = DeliverymanArea.objects.filter(deliveryman=deliveryman)
        areas_data = DeliveryAreaSerializer(areas, many=True).data
        
        data.append({
            'id': deliveryman.id,
            'name': deliveryman.username,
            'phone': deliveryman.phone,
            'areas': areas_data,
            'task_count': deliveryman.task_count
        })
    
    return Response({
        'code': 200,
        'message': '获取成功',
        'data': data
    })

# 将reject方法移到DeliveryTaskViewSet类中
class DeliveryTaskViewSet(viewsets.ModelViewSet):
    queryset = DeliveryTask.objects.all()
    serializer_class = DeliveryTaskSerializer
    # 移除权限检查
    # permission_classes = [permissions.IsAuthenticated]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['status', 'deliveryman', 'priority']
    search_fields = ['delivery_number', 'sales_order__order_number', 'sales_order__customer__username']
    ordering_fields = ['created_at', 'priority', 'estimated_delivery_time']
    ordering = ['-created_at']
    
    # 移除权限方法
    # def get_permissions(self):
    #     if self.action in ['create', 'update', 'partial_update', 'destroy']:
    #         return [IsAdmin() | DeliveryAdminPermission()]
    #     elif self.action in ['assign', 'update_status']:
    #         return [DeliverymanPermission() | IsAdmin() | DeliveryAdminPermission()]
    #     return [permissions.IsAuthenticated()]
    
    def get_queryset(self):
        # 修改为返回所有数据，不再根据用户角色过滤
        return DeliveryTask.objects.all()
    
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        
        # 处理查询参数
        order_number = request.query_params.get('order_number')
        customer_name = request.query_params.get('customer_name')
        
        if order_number:
            queryset = queryset.filter(sales_order__order_number__icontains=order_number)
        if customer_name:
            queryset = queryset.filter(sales_order__customer__username__icontains=customer_name)
        
        # 自定义排序：将等待手动分配且被拒绝两次及以上的任务排在最前面
        # 使用Case/When进行条件排序
        from django.db.models import Case, When, Value, IntegerField
        
        queryset = queryset.annotate(
            custom_order=Case(
                # 第一优先级：等待手动分配且拒绝次数>=2的任务
                When(status='awaiting_manual_assignment', rejection_count__gte=2, then=Value(1)),
                # 第二优先级：其他任务
                default=Value(2),
                output_field=IntegerField()
            )
        ).order_by('custom_order', '-created_at')  # 首先按自定义顺序，然后按创建时间降序
        
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response({
                'code': 200,
                'message': '获取成功',
                'data': {
                    'total': self.paginator.page.paginator.count,
                    'items': serializer.data
                }
            })
        
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': {
                'items': serializer.data
            }
        })
    
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({
            'code': 200,
            'message': '获取成功',
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'])
    def assign(self, request, pk=None):
        """分配配送任务"""
        delivery_task = self.get_object()
        deliveryman_id = request.data.get('deliveryman_id')
        priority = request.data.get('priority')
        estimated_delivery_time = request.data.get('estimated_delivery_time')
        note = request.data.get('note')
        
        # 更新配送任务
        if deliveryman_id:
            delivery_task.deliveryman_id = deliveryman_id
            delivery_task.status = 'assigned'
            delivery_task.note = note if not delivery_task.note else f"{delivery_task.note}\n{note}"
            delivery_task.save()
            
            # 移除这段代码，不再在强制分配时更新订单状态
            # if delivery_task.sales_order and delivery_task.sales_order.status == 'paid':
            #     delivery_task.sales_order.status = 'shipped'
            #     delivery_task.sales_order.save()
        
        if priority:
            delivery_task.priority = priority
            
        if estimated_delivery_time:
            delivery_task.estimated_delivery_time = estimated_delivery_time
            
        if note:
            delivery_task.note = note
            
        delivery_task.save()
        
        # 创建状态记录
        DeliveryStatusRecord.objects.create(
            delivery_task=delivery_task,
            status='assigned',
            operator=request.user,
            note=f"任务已分配给配送员ID: {deliveryman_id}"
        )
        
        return Response({
            'code': 200,
            'message': '分配成功'
        })
    
    @action(detail=True, methods=['post'])
    def status(self, request, pk=None):
        """更新配送任务状态"""
        delivery_task = self.get_object()
        new_status = request.data.get('status')
        location = request.data.get('location', '')
        note = request.data.get('note', '')
        
        if new_status not in dict(DeliveryTask.STATUS_CHOICES):
            return Response({
                'code': 400,
                'message': '无效的状态'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 更新配送任务状态
        delivery_task.status = new_status
        
        # 如果状态是已完成，记录实际配送时间并更新订单状态
        if new_status == 'completed':
            delivery_task.actual_delivery_time = timezone.now()
            # 更新订单状态
            delivery_task.sales_order.status = 'completed'
            delivery_task.sales_order.save()
        # 如果状态是配送中，确保订单状态为已发货，并减少库存
        elif new_status == 'delivering':
            if delivery_task.sales_order and delivery_task.sales_order.status != 'shipped':
                # 更新订单状态为已发货
                delivery_task.sales_order.status = 'shipped'
                delivery_task.sales_order.save()
                
                # 减少库存
                from warehouse.models import Inventory, InventoryRecord
                order = delivery_task.sales_order
                
                # 遍历订单项，减少对应仓库的库存
                for order_item in order.items.all():
                    try:
                        inventory = Inventory.objects.get(
                            product_id=order_item.product_id, 
                            warehouse_id=order_item.warehouse_id
                        )
                        
                        # 检查库存是否足够
                        if inventory.current_stock < order_item.quantity:
                            # 库存不足，记录错误但继续处理
                            note += f"\n商品 {order_item.product.name} 库存不足，当前库存: {inventory.current_stock}, 需要: {order_item.quantity}"
                            continue
                        
                        # 减少库存
                        inventory.current_stock -= order_item.quantity
                        inventory.save()
                        
                        # 创建库存记录
                        InventoryRecord.objects.create(
                            inventory=inventory,
                            quantity=order_item.quantity,
                            operation_type='out',
                            operator=request.user,
                            related_order=order,
                            note=f'销售订单 {order.order_number} 出库 (配送任务状态变更为配送中)'
                        )
                    except Inventory.DoesNotExist:
                        # 库存记录不存在，记录错误但继续处理
                        note += f"\n商品ID {order_item.product_id} 在仓库ID {order_item.warehouse_id} 不存在库存记录"
        
        delivery_task.save()
        
        # 创建状态记录
        DeliveryStatusRecord.objects.create(
            delivery_task=delivery_task,
            status=new_status,
            operator=request.user,
            location=location,
            note=note
        )
        
        return Response({
            'code': 200,
            'message': '更新成功'
        })

    @action(detail=True, methods=['post'])
    def reject(self, request, pk=None):
        """配送员拒绝配送任务"""
        delivery_task = self.get_object()
        reason = request.data.get('reason', '')
        
        # 只有已分配状态的任务可以拒绝
        if delivery_task.status != 'assigned':
            return Response({
                'code': 400,
                'message': '只有已分配的任务可以拒绝'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 添加检查：如果任务已被拒绝两次或以上，不允许再次拒绝
        if delivery_task.rejection_count >= 2:
            return Response({
                'code': 400,
                'message': '该任务已被拒绝两次，不能再次拒绝'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 记录原配送员信息
        original_deliveryman = delivery_task.deliveryman
        
        # 增加拒绝计数
        delivery_task.rejection_count += 1
        
        # 根据拒绝次数决定后续流程
        if delivery_task.rejection_count >= 2:
            # 第二次拒绝，状态变为等待手动分配
            delivery_task.status = 'awaiting_manual_assignment'
            delivery_task.deliveryman = None
            delivery_task.save()
            
            # 创建状态记录
            DeliveryStatusRecord.objects.create(
                delivery_task=delivery_task,
                status='rejected',  # 记录拒绝动作
                operator=request.user,
                note=f"配送员 {original_deliveryman.username} 第二次拒绝任务，原因: {reason}。任务已转为等待手动分配状态。"
            )
            
            # 如果订单状态是已发货，将其改回已付款
            if delivery_task.sales_order and delivery_task.sales_order.status == 'shipped':
                delivery_task.sales_order.status = 'paid'
                delivery_task.sales_order.save()
            
            return Response({
                'code': 200,
                'message': '拒绝成功，任务已转为等待手动分配状态'
            })
        else:
            # 第一次拒绝，状态变为已拒绝，等待重新分配
            delivery_task.status = 'rejected'
            delivery_task.deliveryman = None
            delivery_task.save()
            
            # 创建状态记录
            DeliveryStatusRecord.objects.create(
                delivery_task=delivery_task,
                status='rejected',
                operator=request.user,
                note=f"配送员 {original_deliveryman.username} 拒绝任务，原因: {reason}"
            )
            
            # 如果订单状态是已发货，将其改回已付款
            if delivery_task.sales_order and delivery_task.sales_order.status == 'shipped':
                delivery_task.sales_order.status = 'paid'
                delivery_task.sales_order.save()
            
            # 尝试自动重新分配
            from orders.views import OrderViewSet
            order_viewset = OrderViewSet()
            result = order_viewset.auto_assign_deliveryman(delivery_task, request.user)
            
            if result:
                return Response({
                    'code': 200,
                    'message': '拒绝成功，任务已自动重新分配给其他配送员'
                })
            else:
                # 如果自动分配失败，状态保持为rejected
                return Response({
                    'code': 200,
                    'message': '拒绝成功，但未找到合适的配送员重新分配'
                })

# 在DeliveryTaskViewSet类中添加自动分配方法
@action(detail=True, methods=['post'])
def auto_assign(self, request, pk=None):
    """自动分配配送任务"""
    delivery_task = self.get_object()
    
    # 只有待处理状态的任务可以自动分配
    if delivery_task.status != 'pending':
        return Response({
            'code': 400,
            'message': '只有待处理的任务可以自动分配'
        }, status=status.HTTP_400_BAD_REQUEST)
    
    # 调用订单视图中的自动分配方法
    from orders.views import OrderViewSet
    order_viewset = OrderViewSet()
    result = order_viewset.auto_assign_deliveryman(delivery_task, request.user)
    
    if result:
        return Response({
            'code': 200,
            'message': '自动分配成功'
        })
    else:
        return Response({
            'code': 400,
            'message': '自动分配失败，未找到合适的配送员'
        }, status=status.HTTP_400_BAD_REQUEST)
